/*
 * Trade.h
 *
 *  Created on: 2013. 10. 14.
 *      Author: mega@gamevil.com
 */

#ifndef TRADE_H_
#define TRADE_H_

#include "Item.h"

namespace ProjectZ {
class User;
} /*ProjectZ*/

namespace ProjectZ { namespace NLogic {

class Trade
{
public:
	struct SoldItem
	{
		uint64_t seq;
		int classType;
		int sheetType;
		int tid;
		int curRefineStep;
		int itemQuality;
		int itemPrice;
		time_t soldTime;
	};

	struct Key
	{
		uint64_t tradeSeq;
		int classType;
		int sheetType;

		Key() : tradeSeq(0), classType(0), sheetType(0) {}
		Key(uint64_t rSeq, int rClass, int rSheet) : tradeSeq(rSeq), classType(rClass), sheetType(rSheet) {}

		bool operator == (const Key & rSide) const
		{
			if (this->tradeSeq == rSide.tradeSeq
					&& this->classType == rSide.classType
					&& this->sheetType == rSide.sheetType)
			{
				return true;
			}

			return false;
		}

		bool operator < (const Key & rSide) const
		{
			if (this->tradeSeq < rSide.tradeSeq)
			{
				return true;
			}
			else if (this->tradeSeq == rSide.tradeSeq)
			{
				if (this->classType < rSide.classType)
				{
					return true;
				}
				else if (this->classType == rSide.classType)
				{
					if (this->sheetType < rSide.sheetType)
					{
						return true;
					}
				}

			}

			return false;
		}
	};

public:
	class TradeItem
	{
	public:
		struct Data
		{
			int reg_user_seq;			// 아이템 판매 유저 Seq
			int reg_slot_seq;			// 아이템 판매 유저 캐릭터 Seq
			int buyer_slot_seq;			// 아이템 구매 유저 캐릭터 Seq
			int item_price;				// 아이템 판매 가격
			int status;					// 아이템 상태 (0:판매중, 1:판매완료, 2:판매취소)
			int sell_info_visible;		// 아이템 판매 정보 노출 여부 (1:노출완료, 0:비노출), 아이템 판매 정보는 판매되었을때 단 한번만 노출.

			time_t reg_date;			// 아이템 판매 등록 시간
			time_t limit_date;			// 거래소에 해당 아이템의 노출 종료 시간
			time_t sold_date;			// 아이템 판매 완료 시간

			Toolkit::Str<32> reg_user_nickname;

			struct NLogic::Item::Data item;

			Data()
			{
				reg_user_seq = 0;
				reg_slot_seq = 0;
				buyer_slot_seq = 0;
				item_price = 0;
				status = 0;
				sell_info_visible = 0;

				reg_date = 0;
				limit_date = 0;
				sold_date = 0;

				reg_user_nickname.Clear();
				item.Clear();
			}

			void Init()
			{
				reg_user_seq = 0;
				reg_slot_seq = 0;
				buyer_slot_seq = 0;
				item_price = 0;
				status = 0;
				sell_info_visible = 0;

				reg_date = 0;
				limit_date = 0;
				sold_date = 0;

				reg_user_nickname.Clear();
				item.Clear();
			}
		};

	public:
		TradeItem() :  _user(NULL), _tradeSeq(0), _tradeSelfSeq(0) {};
		virtual ~TradeItem() {};

	public:
		void			Initialize() { _tradeSeq = 0; _tradeSelfSeq = 0; _user = NULL; }
		void 			Finalize() { };

	public:
		void			Open_Normal(uint64_t tradeSeq, Data & data, User * pUser);
		void			Open_FromDatabase(uint64_t tradeSeq, uint64_t tradeSelfSeq, Data & data, User * pUser);
		Data &			GetData() { return _data; }

		uint64_t		GetTradeSeq() { return _tradeSeq; }
		uint64_t		GetTradeSelfSeq() { return _tradeSelfSeq; }

		bool			SelectDatabaseTradeItemDetailInfo();
		int				SelectDatabaseTradeItemStatus();
		bool			UpdateDatabaseCancelStatus();
		bool			UpdateDatabaseSoldoutStatus();

		void			WriteToItemPacket(::Network::Packet * pPacket);

	private:
		Data		_data;
		User * 		_user;
		uint64_t	_tradeSeq;
		uint64_t	_tradeSelfSeq;
	};

public:
	Trade(User * pUser);
	virtual ~Trade();

	void		Initialize();
	void		Finalize();

public:
	typedef		std::map<NLogic::Trade::Key, NLogic::Trade::TradeItem *> REGISTITEMTREE;
	typedef		std::vector<NLogic::Trade::SoldItem> SOLDITEMVECTOR;

public:
	bool							IsExistTradeItemData(NLogic::Trade::Key & clsKey);
	bool							AddTradeItemData(NLogic::Trade::TradeItem * pTradeItem);
	void							RemoveTradeItemData(NLogic::Trade::Key & clsKey);
	NLogic::Trade::TradeItem *		GetTradeItemData(NLogic::Trade::Key & clsKey);

//	void							OnSoldoutItemVisibleStatus() { _bSoldItemLoad = true; }
//	void							OffSoldoutItemVisibleStatus() { _bSoldItemLoad = false; }
//	bool							IsSoldoutItemVisible() { return _bSoldItemLoad; }
//
//	void							SetSoldItemLoadStatus(bool bLoad) { _bSoldItemLoad = bLoad; }
//	bool							GetSoldItemLoadStatus() { return _bSoldItemLoad; }

	void							TradeItemLoadToDatabase();

	bool							SoldItemLoadToDatabase();
	bool							UpdateDatabaseSoldItemShowStatus(uint64_t seq);

	REGISTITEMTREE &				GetTradeItemTree() { return clsTradeItemTree; }
	SOLDITEMVECTOR &				GetSoldItemVector() { return clsSoldItemVector; }

private:
	REGISTITEMTREE		clsTradeItemTree;
	SOLDITEMVECTOR		clsSoldItemVector;
	User *				_user;
	bool				_bSoldItemLoad;
	bool				_bLoad;
};

} /*NLogic*/ } /* namespace ProjectZ */


#endif /* TRADE_H_ */
